/*
 * File    : /services/UserService.js
 * Time    : 2021-03-30 21:07:26
 * Author  : Gray Snail
 * Version : 1.0
 * Contact : shtao2011@sina.com
 * License : Copyright (c) 2021 Gray Snail
 * Desc    : None
 */

const Password = require('node-php-password')
const logger = require('../modules/logger').logger()
const { Op } = require('sequelize')
const { AclUser, AclUserRole, AclRole, Sequelize } = require('../models')
const Page = require('../modules/page')

/**
 * 获取所有管理员
 * @param  {[type]}   conditions 查询条件
 * 查询条件统一规范
 * conditions {
 *  "query" : 关键词查询
 * }
 * @param  {Function} cb   回调函数
 */
module.exports.list = async function (conditions, page = new Page()) {
  const where = {
    username: { [Op.like]: `%${conditions.query}%` },
  }
  const count = await AclUser.count({ where })
  const offset = (page.number - 1) * page.size

  const limit = page.size
  const users = await AclUser.findAll({
    attributes: ['id', 'username', 'email', 'phone', 'status'],
    where,
    limit,
    offset,
  })

  return {
    total: count,
    pagenum: page.number,
    list: users.map((user) => user.toJSON()),
  }
}

module.exports.userRoles = async function () {
  const users = await AclUser.findAll({
    attributes: ['id', 'username'],
    include: {
      model: AclUserRole,
      as: 'roleIDs',
      attributes: ['role_id'],
    },
  })
  return users.map((item) => {
    return item.toJSON()
  })
}

/**
 * 创建管理员
 *
 * @param  {[type]}   user 用户数据集
 */
module.exports.create = async function (user) {
  user.password = Password.hash(user.password)
  const res = await AclUser.create(user)
  return res.toJSON()
}

/**
 * 更新管理员信息
 *
 * @param  {[type]}   user 管理员信息
 * @param  {Function} cb     回调函数
 */
module.exports.update = async function (user) {
  const userDb = await AclUser.findByPk(user.id)
  if (user.password) {
    user.password = Password.hash(user.password)
  }
  await userDb.update(user)
  return true
}

/**
 * 通过管理员 ID 获取管理员信息
 *
 * @param  {[type]}   id 管理员 ID
 */
module.exports.getById = async function (id) {
  const user = await AclUser.findByPk(id)
  return user.toJSON()
}

/**
 * 通过管理员 ID 进行删除操作
 *
 * @param  {[type]}   id 管理员ID
 */
module.exports.delete = async function (id) {
  const result = await Sequelize.transaction(async (t) => {
    const res = await AclUser.destroy({ where: { id }, transaction: t })
    await AclUserRole.destroy({ where: { user_id: id }, transaction: t })
    return res
  })
  return result
}

/**
 * 为管理员设置角色
 *
 * @param {[type]}   id  管理员ID
 * @param {[type]}   rids 角色ID数组
 */
module.exports.setRole = async function (id, rids) {
  const userRoles = rids.map((rid) => {
    return { user_id: id, role_id: rid }
  })
  const result = await Sequelize.transaction(async (t) => {
    await AclUserRole.destroy({ where: { user_id: id }, transaction: t })
    const res = await AclUserRole.bulkCreate(userRoles, { transaction: t })
    return res.length
  })
  return result
}

module.exports.updateState = async function (id, state) {
  const user = await AclUser.findByPk(id, { attributes: ['id', 'status'] })
  await user.update({ status: state })
  return true
}

/**
 * 管理员登录
 * @param  {[type]}   username 用户名
 * @param  {[type]}   password 密码
 */
module.exports.login = async function (username, password) {
  logger.debug('login => username:%s,password:%s', username, password)
  const userDb = await AclUser.findOne({
    where: { username },
    attributes: ['id', 'username', 'password', 'email', 'phone', 'status'],
    include: {
      model: AclRole,
      as: 'roles',
      attributes: ['id', 'name'],
      through: { attributes: [] },
    },
  })
  if (!userDb.status) {
    throw new Error('该用户已经被禁用')
  }
  if (!userDb.roles) {
    throw new Error('该用户没有权限登录')
  }
  if (!Password.verify(password, userDb.password)) {
    throw new Error('密码错误')
  }
  const userObj = userDb.toJSON()
  Reflect.deleteProperty(userObj, 'password')
  return userObj
}
